package org.epes.laboratory.vcn.service.test;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.epes.laboratory.vcn.application.test.OptimizationApplication;

public class RunOptimizationTask implements JavaDelegate {

	public void execute(DelegateExecution execution) throws Exception {
		
		// 2.6 Build OptimizationApplication application to hold all variables - INIT
		
		OptimizationApplication oa = new OptimizationApplication();		
		 
		// x0y0
		String x0y0 = (String) execution.getVariable("x0y0");
		String x0 = x0y0.split(",")[0];
		String y0 = x0y0.split(",")[1];
		
		oa.setX0(Integer.parseInt(x0));
		oa.setY0(Integer.parseInt(y0));
		
		// x1y1
		String x1y1 = (String) execution.getVariable("x1y1");
		String x1 = x1y1.split(",")[0];
		String y1 = x1y1.split(",")[1];
		
		oa.setX1(Integer.parseInt(x1));
		oa.setY1(Integer.parseInt(y1));
		
		// x2y2
		String x2y2 = (String) execution.getVariable("x2y2");
		String x2 = x2y2.split(",")[0];
		String y2 = x2y2.split(",")[1];
		
		oa.setX2(Integer.parseInt(x2));
		oa.setY2(Integer.parseInt(y2));
		
		// x3y3
		String x3y3 = (String) execution.getVariable("x3y3");
		String x3 = x3y3.split(",")[0];
		String y3 = x3y3.split(",")[1];
		
		oa.setX3(Integer.parseInt(x3));
		oa.setY3(Integer.parseInt(y3));
		
		// x4y4
		String x4y4 = (String) execution.getVariable("x4y4");
		String x4 = x4y4.split(",")[0];
		String y4 = x4y4.split(",")[1];
		
		oa.setX4(Integer.parseInt(x4));
		oa.setY4(Integer.parseInt(y4));
		
		// co2ManagedKnowledge		
		oa.setCo2ManagedKnowledge((Long) execution.getVariable("co2ManagedKnowledge"));
		
		// set OptimizationApplication as a new process variable
		//execution.setVariable("optimizationApplication", oa);
		
		// 2.6 Build OptimizationApplication application to hold all variables - END
		
		// 2.1 Read the excel template - INIT
		
		String excelSimulatorTemplatePath = Thread.currentThread().getContextClassLoader().
				getResource("templates/EPES_Lab_sim_tool_01.xlsx").getPath();
		InputStream excelSimulatorTemplate = new FileInputStream(excelSimulatorTemplatePath);
		
		XSSFWorkbook excelWorkbook = new XSSFWorkbook(excelSimulatorTemplate);
		XSSFFormulaEvaluator evaluator = new XSSFFormulaEvaluator(excelWorkbook);
		Sheet sheet = excelWorkbook.getSheetAt(0);		
		
		// 2.1 Read the excel template - END
		
		// 2.2 Fill in the template with OptimizationApplication variables - INIT
		
		// Set x0, y0 values
		setCellValue(oa.getX0(), 2, 2, sheet);
		setCellValue(oa.getY0(), 2, 3, sheet);
			
		// Set x1, y1 values
		setCellValue(oa.getX1(), 3, 2, sheet);
		setCellValue(oa.getY1(), 3, 3, sheet);
		
		// Set x2, y2 values
		setCellValue(oa.getX2(), 4, 2, sheet);
		setCellValue(oa.getY2(), 4, 3, sheet);
		
		// Set x3, y3 values
		setCellValue(oa.getX3(), 5, 2, sheet);
		setCellValue(oa.getY3(), 5, 3, sheet);
		
		// Set x4, y4 values
		setCellValue(oa.getX4(), 6, 2, sheet);
		setCellValue(oa.getY4(), 6, 3, sheet);
		
		// Set co2ManagedKnowledge value
		setCellValue(oa.getCo2ManagedKnowledge(), 9, 7, sheet);
		
		// Evaluate all the cells with formulas
		evaluator.evaluateAll();
		
		// Write the sheet into a file				
		ByteArrayOutputStream excelSimulator = new ByteArrayOutputStream(1024);
		excelWorkbook.write(excelSimulator);		
		OutputStream outputStream = new FileOutputStream("EPES_Lab_sim_tool_01.xlsx");
		excelSimulator.writeTo(outputStream);
		System.out.println("EPES: The file 'EPES_Lab_sim_tool_01.xlsx' has been written");
		
		// 2.2 Fill in the template with OptimizationApplication variables - END
		
		// 2.3 Send the excelSimulator to SOMO through REST or other Web Services technology - INIT
		// TODO Implement Step 2.3
		// 2.3 Send the excelSimulator to SOMO through REST or other Web Services technology - INIT
		
		// 2.4 Get the solution from SOMO - INIT
		// TODO Implement Step 2.4
		// 2.4 Get the solution from SOMO - END
		
		// 2.5 Set the solution as an OptimizationApplication field and set 
		// optimizationApplication as a new process variable - END
		
		// TODO Implement Step 2.5		
		ByteArrayOutputStream excelSolution = excelSimulator;
		oa.setExcelSolution(excelSolution.toByteArray());
		
		execution.setVariable("optimizationApplication", oa);
		
		// 2.5 Set the solution as an OptimizationApplication field and set 
		// optimizationApplication as a new process variable - END		
	}
	
	private void setCellValue(int number, int rowNumber, int cellNumber,
			Sheet sheet) {
		Row row = sheet.getRow(rowNumber);
		Cell cell = row.getCell(cellNumber);
		if (cell == null) {
			cell = row.createCell(cellNumber);
		}
		cell.setCellValue(number);		
	}
	
	private void setCellValue(long number, int rowNumber, int cellNumber,
			Sheet sheet) {
		Row row = sheet.getRow(rowNumber);
		Cell cell = row.getCell(cellNumber);
		if (cell == null) {
			cell = row.createCell(cellNumber);
		}
		cell.setCellValue(number);		
	}
}
